#include "StdAfx.h"

MiniMap::MiniMap(std::string szName, Vertex2F position, Vertex2F size)
{
	m_texture = 0;
	m_textureData = 0;
	m_factor = 1.0f;
	m_relation = Vertex2F(0, 0);
	m_vertices[0].z = m_vertices[1].z = m_vertices[2].z = m_vertices[3].z = 0.0f;
	m_vertices[0].rhw = m_vertices[1].rhw = m_vertices[2].rhw = m_vertices[3].rhw = 1.0f;
	m_vertices[0].x = position.x;
	m_vertices[0].y = position.y;
	m_vertices[0].u = 0.0f;
	m_vertices[0].v = 0.0f;

	m_vertices[1].x = position.x + size.x;
	m_vertices[1].y = position.y;
	m_vertices[1].u = 1.0f;
	m_vertices[1].v = 0.0f;

	m_vertices[2].x = position.x + size.x;
	m_vertices[2].y = position.y + size.y;
	m_vertices[2].u = 1.0f;
	m_vertices[2].v = 1.0f;

	m_vertices[3].x = position.x;
	m_vertices[3].y = position.y + size.y;
	m_vertices[3].u = 0.0f;
	m_vertices[3].v = 1.0f;

	InitTexture(szName);
}

ui32 GetChunk(CMpqFile& f)
{
	ui32 sig;
	f.ReadInc(4, &sig);
	return sig;
}

void SkipChunk(CMpqFile& f)
{
	ui32 size;
	f.ReadInc(4, &size);
	f.ModInc(size);
}

void MiniMap::InitTexture(std::string szName)
{
	char name[255];
	sprintf_s<255>(name, "World\\Maps\\%s\\%s.wdl", szName.c_str(), szName.c_str());
	CMpqFile file(name);
	if(!file.IsOpened())
	{
		MessageBoxA(0, name, "Minimap not found!", MB_OK);
		return;
	}
	ui32 offsets[64][64];
	ui32 signature = 0;
	while(signature = GetChunk(file) != 'MAOF')
	{
		SkipChunk(file);
	}
	file.ModInc(4);
	file.ReadInc(64 * 64 * 4, offsets);
	m_textureData = new ui32[64 * 17 * 64 * 17];
	memset(m_textureData, 0, 64 * 17 * 64 * 17 * 4);
	i16 tile[17 * 17];
	for(ui32 i = 0; i < 64; ++i)
	{
		for(ui32 j = 0; j < 64; ++j)
		{
			if(offsets[i][j])
			{
				file.SetInc(offsets[i][j] + 0x08);
				file.ReadInc(17 * 17 * 2, tile);
				for(ui32 k = 0; k < 17; ++k)
				{
					for(ui32 l = 0; l < 17; ++l)
					{
						i16 height = tile[k * 17 + l];
						ui8 r = 0, g = 0, b = 0;

						if(height > 1000)
						{
							r = g = b = 255;
						}
						else if(height > 600)
						{
							float am = (height - 600.0f) / 400.0f;
							r = ui8(0.75f + am * 0.25f * 255);
							g = ui8(0.5f * am * 255);
							b = ui8(am * 255);
						}
						else if(height > 300)
						{
							float am = (height - 300.0f) / 300.0f;
							r = ui8(255 - am * 255);
							g = ui8(1.0f);
							b = ui8(0.0f);
						}
						else if(height > 0)
						{
							float am = height / 300.0f;
							r = ui8(0.75f * am * 255);
							g = ui8(255 - (0.5f * am * 255));
							b = ui8(0);
						}
						else if(height > -100)
						{
							float am = (height + 100.0f) / 100.0f;
							r = ui8(0.0f);
							g = ui8(am * 255);
							b = ui8(255);
						}
						else if(height > -550)
						{
							float am = (height + 550) / (450.0f);
							r = ui8(0.0f);
							g = ui8(0.0f);
							b = ui8(0x7F);
						}
						else if(height > -1000)
						{
							r = ui8(0);
							g = ui8(0);
							b = ui8(0x7F);
						}
						if(k == 0 || l == 0)
							r = g = b = 0x3F;

						m_textureData[(i * 17 + k) * (64 * 17) + j * 17 + l] = (b) | (g << 8) | (r << 16) | (255 << 24);
					}
				}
			}
		}
	}

	HRESULT hRes = sD3D->CreateTexture(64 * 17, 64 * 17, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_texture, 0);
	if(FAILED(hRes))
	{
		MessageBoxA(0, "Minimap texture create failed!", "", MB_OK);
	}

	IDirect3DSurface9* surf;
	m_texture->GetSurfaceLevel(0, &surf);
	D3DSURFACE_DESC desc;
	surf->GetDesc(&desc);
	RECT r;
	r.left = r.top = 0;
	r.right = desc.Width;
	r.bottom = desc.Height;
	if(D3DXLoadSurfaceFromMemory(surf, 0, 0, m_textureData, D3DFMT_A8R8G8B8, 4 * r.right, 0, &r, D3DX_DEFAULT, 0) != D3D_OK)
	{
		MessageBox(0, "Load from Memory", "Failed!", MB_OK);
	}
}

void MiniMap::Draw()
{
	sD3D->SetFVF(VERTEX3FRHWT);
	sD3D->SetTexture(0, m_texture);
	sD3D->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_vertices, sizeof(Vertex3FRHWT));
}

void MiniMap::SetScale(float factor)
{
	m_factor = factor;
	m_vertices[0].u = m_vertices[0].v = m_vertices[1].v = m_vertices[3].u = (0.5f - factor / 2.0f);
	m_vertices[1].u = m_vertices[2].u = m_vertices[2].v = m_vertices[3].v = 1.0f - (0.5f - factor / 2.0f);
	for(ui32 i = 0; i < 4; ++i)
	{
		m_vertices[i].u += m_relation.x;
		m_vertices[i].v += m_relation.y;
	}
}

void MiniMap::SetRelation(Vertex2F relation)
{
	m_relation = relation;
	m_vertices[0].u = m_vertices[0].v = m_vertices[1].v = m_vertices[3].u = (0.5f - m_factor / 2.0f);
	m_vertices[1].u = m_vertices[2].u = m_vertices[2].v = m_vertices[3].v = 1.0f - (0.5f - m_factor / 2.0f);
	for(ui32 i = 0; i < 4; ++i)
	{
		m_vertices[i].u += m_relation.x;
		m_vertices[i].v += m_relation.y;
	}
}

void MiniMap::BeforeReset()
{
	while(m_texture && m_texture->Release());
}

void MiniMap::OnReset()
{
	if(!m_textureData)
	{

	}

	HRESULT hRes = sD3D->CreateTexture(64 * 17, 64 * 17, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_texture, 0);
	if(FAILED(hRes))
	{
		MessageBoxA(0, "Minimap texture create failed!", "", MB_OK);
	}

	IDirect3DSurface9* surf;
	m_texture->GetSurfaceLevel(0, &surf);
	D3DSURFACE_DESC desc;
	surf->GetDesc(&desc);
	RECT r;
	r.left = r.top = 0;
	r.right = desc.Width;
	r.bottom = desc.Height;
	if(D3DXLoadSurfaceFromMemory(surf, 0, 0, m_textureData, D3DFMT_A8R8G8B8, 4 * r.right, 0, &r, D3DX_DEFAULT, 0) != D3D_OK)
	{
		MessageBox(0, "Load from Memory", "Failed!", MB_OK);
	}
}

void MiniMap::unload() {
	m_texture->Release();
	delete [] m_textureData;
}